#include <wayland-client.h>
#include "xdg-shell-client-protocol.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

struct wl_display *display = NULL;
struct wl_compositor *compositor = NULL;
struct wl_surface *surface = NULL;
struct xdg_wm_base *xdg_wm_base = NULL;
struct xdg_surface *xdg_surface = NULL;
struct xdg_toplevel *xdg_toplevel = NULL;
struct wl_shm *shm = NULL;
struct wl_buffer *buffer = NULL;

static void registry_handler(void *data, struct wl_registry *registry,
                             uint32_t id, const char *interface, uint32_t version) {
    if (strcmp(interface, "wl_compositor") == 0) {
        compositor = wl_registry_bind(registry, id, &wl_compositor_interface, 1);
    } else if (strcmp(interface, "xdg_wm_base") == 0) {
        xdg_wm_base = wl_registry_bind(registry, id, &xdg_wm_base_interface, 1);
    } else if (strcmp(interface, "wl_shm") == 0) {
        shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
    }
}

static const struct wl_registry_listener registry_listener = {
    .global = registry_handler,
    .global_remove = NULL,
};

// 创建缓冲区
struct wl_buffer *create_buffer(int width, int height) {
    int stride = width * 4; // 每像素4字节 (RGBA)
    int size = stride * height;

    int fd = memfd_create("buffer", MFD_CLOEXEC);
    ftruncate(fd, size);

    void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

    struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, size);
    struct wl_buffer *buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888);
    wl_shm_pool_destroy(pool);

    close(fd);

    // 初始化缓冲区为白色
    memset(data, 0xff, size);
    munmap(data, size);

    return buffer;
}

int main() {
    display = wl_display_connect(NULL);
    if (!display) {
        fprintf(stderr, "无法连接到 Wayland 显示服务器\n");
        return -1;
    }

    struct wl_registry *registry = wl_display_get_registry(display);
    wl_registry_add_listener(registry, &registry_listener, NULL);

    wl_display_dispatch(display);
    wl_display_roundtrip(display);

    if (!compositor || !xdg_wm_base || !shm) {
        fprintf(stderr, "无法获取所需接口\n");
        return -1;
    }

    // 创建表面
    surface = wl_compositor_create_surface(compositor);
    xdg_surface = xdg_wm_base_get_xdg_surface(xdg_wm_base, surface);
    xdg_toplevel = xdg_surface_get_toplevel(xdg_surface);

    // 设置窗口标题
    xdg_toplevel_set_title(xdg_toplevel, "Wayland 窗口");
    xdg_toplevel_set_min_size(xdg_toplevel, 640, 480); // 设置最小尺寸
    xdg_toplevel_set_max_size(xdg_toplevel, 800, 600); // 设置最大尺寸

    // 监听ping事件
    static const struct xdg_wm_base_listener base_listener = {
        .ping = [](void *data, struct xdg_wm_base *base, uint32_t serial) {
            xdg_wm_base_pong(base, serial);
        },
    };
    xdg_wm_base_add_listener(xdg_wm_base, &base_listener, NULL);

    // 创建缓冲区并设置大小
    buffer = create_buffer(800, 600); // 宽 800px，高 600px
    wl_surface_attach(surface, buffer, 0, 0);
    wl_surface_commit(surface);

    // 主循环
    while (wl_display_dispatch(display) != -1) {
        // 处理事件
    }

    // 清理资源
    wl_buffer_destroy(buffer);
    xdg_toplevel_destroy(xdg_toplevel);
    xdg_surface_destroy(xdg_surface);
    wl_surface_destroy(surface);
    wl_display_disconnect(display);

    return 0;
}
